package jastgen.generator;

import java.io.PrintWriter;
import java.util.List;

import jastgen.nodes.Field;
import jastgen.nodes.InterfaceDef;
import jastgen.nodes.Type;

import static jastgen.generator.Generator.*;

class InterfaceBodyGenerator implements BodyGenerator {

	private final List<String> visitReturnTypes;
	private final InterfaceDef node;

	InterfaceBodyGenerator(
			final List<String> visitReturnTypes,
			final InterfaceDef node)
	{
		this.visitReturnTypes = visitReturnTypes;
		this.node = node;
	}

	public void generate(
			final PrintWriter out)
	{
		generateInterfaceBody(out, node);
	}

	private void generateInterfaceBody(
			final PrintWriter out,
			final InterfaceDef node)
	{
		final String n  = node.getName();
		final String bn = node.getBaseName();

		out.print("public abstract class " + n);

		final String ext = "extends ComparableImpl<" + n + "> implements Node";

		// クラス名が7文字を超えると1行に収まらない
		// (クラス名x2を除いた文字数は65, クラス名は2回出力)
		if(n.length() > 7) {
			out.println();
			out.print("	");
			out.println(ext);
			out.print("{");
		} else {
			out.println(" " + ext + " {");
		}

		if(!node.getFields().isEmpty())
			out.println();
		for(final Field f : node.getFields()) {
			final String mn = f.getNameInMethod();
			final Type t = f.getType();
			out.println("	public abstract " + t + " get" + mn + "();");
		}

		out.println();
		out.print("	public abstract ");
		printTypeParams(out, visitReturnTypes, "\t                 ");
		out.println();
		out.println("	" + toVisitReturnType(bn) + " visit(");
		out.print("		Visitor");
		printTypeParams(out, visitReturnTypes, "\t\t        ");
		out.println(" v);");
		out.println("}");
	}
}
